/**
 * 
 */
package cn.bblocks.cacheTest.suport;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.google.common.base.Strings;

import lombok.extern.slf4j.Slf4j;

/**
 * FFMPEG 的相关操作
 * 
 *
 * @author Administrator
 */
@Slf4j
public class FFMpegUtil {

    //Windows下 ffmpeg.exe的路径
	private static String ffmpegEXE = "D:\\soft\\ffmpeg-20190623-ffa64a4-win64-static\\bin\\ffmpeg.exe";

    //Linux与mac下  ffmpeg的路径
//    private static String ffmpegEXE = "/developer/ffmpeg-4.0/bin/ffmpeg";


    /**
     * @param videoInputPath 视频的输入路径
     * @param videoOutPath   视频的输出路径
     * @throws Exception
     */
    // 拷贝视频，并指定新的视频的名字以及格式
    // ffmpeg.exe -i old.mp4 new.avi
    public static void convetor(String videoInputPath, String videoOutPath) throws Exception {

        List<String> command = new ArrayList<String>();
        command.add(ffmpegEXE);
        command.add("-i");
        command.add(videoInputPath);
        command.add(videoOutPath);
        ProcessBuilder builder = new ProcessBuilder(command);
        Process process = null;
        try {
            process = builder.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 使用这种方式会在瞬间大量消耗CPU和内存等系统资源，所以这里我们需要对流进行处理
        InputStream errorStream = process.getErrorStream();
        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
        BufferedReader br = new BufferedReader(inputStreamReader);

        String line = "";
        while ((line = br.readLine()) != null) {
        }
        if (br != null) {
            br.close();
        }
        if (inputStreamReader != null) {
            inputStreamReader.close();
        }
        if (errorStream != null) {
            errorStream.close();
        }

    }

    /**
     * @param videoInputPath 原视频的路径
     * @param audioInputPath 音频的路径
     * @param videoOutPath   视频与音频结合之后的视频的路径
     * @param time           视频的长度 ,单位为 s
     * @throws Exception
     */
    // 将视频和音频结合，并指定视频的长度，同时生成结合之后的视频文件
    // ffmpeg.exe -i tsd.mp4 -i "周笔畅+-+最美的期待.mp3" -t 7 -y new.avi
    public static void convetor(String videoInputPath, String audioInputPath, String videoOutPath, double time)
            throws Exception {

        List<String> command = new ArrayList<String>();
        command.add(ffmpegEXE);
        command.add("-i");
        command.add(videoInputPath);
        command.add("-i");
        command.add(audioInputPath);
        command.add("-t");
        command.add(String.valueOf(time));
        command.add("-y");
        command.add(videoOutPath);
        ProcessBuilder builder = new ProcessBuilder(command);
        Process process = null;
        try {
            process = builder.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 使用这种方式会在瞬间大量消耗CPU和内存等系统资源，所以这里我们需要对流进行处理
        InputStream errorStream = process.getErrorStream();
        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
        BufferedReader br = new BufferedReader(inputStreamReader);

        String line = "";
        while ((line = br.readLine()) != null) {
        	System.out.println(line);
        }
        if (br != null) {
            br.close();
        }
        if (inputStreamReader != null) {
            inputStreamReader.close();
        }
        if (errorStream != null) {
            errorStream.close();
        }

    }
    
    
    /**  
    * @Title: volumeAdd  
    * @author jzhao
    * @Description: 音量调整
    * @param @param inputPath
    * @param @param outPath
    * @param @param adddb 增加值（db）
    * @param @throws Exception
    * @return void
    * @throws  
    */  
    public static boolean volumeAdd(String inputPath,String outPath,double adddb) throws Exception{
    	//ffmpeg -i local_audio_bb.aac -filter:a "volume=7dB" local_audio_bb_2.aac -y
    	
    	log.debug("调整：{}音量增加：{}",inputPath,adddb);
    	List<String> command = new ArrayList<String>();
        command.add(ffmpegEXE);
        command.add("-i");
        command.add(inputPath);
        command.add("-i");
        command.add(inputPath);
        command.add("-filter:a");
        command.add("\"volume="+adddb+"dB\"");
        command.add(outPath);
        command.add("-y");
        
        log.info("音量调整命令：{}",StringUtils.join(command.toArray(), " " ));
        
        ProcessBuilder builder = new ProcessBuilder(command);
        Process process = null;
        try {
            process = builder.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 使用这种方式会在瞬间大量消耗CPU和内存等系统资源，所以这里我们需要对流进行处理
        InputStream errorStream = process.getErrorStream();
        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
        BufferedReader br = new BufferedReader(inputStreamReader);
        
        String last = null;
        String line = "";
        while ((line = br.readLine()) != null) {
        	last = line;
        	//System.out.println(line);
        }
        if (br != null) {
            br.close();
        }
        if (inputStreamReader != null) {
            inputStreamReader.close();
        }
        if (errorStream != null) {
            errorStream.close();
        }
        //检测文件是否存在以及大小
        long fileSize = getFileSize(outPath);
        if(fileSize <=0) {
        	log.error("增加音量{}失败：{}",inputPath,last);
        	return false;	
        }else {
        	
        	log.info("调整：{}音量增加：{}成功，至文件：{}",inputPath,adddb,outPath);
        	return true;   
        }
        	
    }
    
    /**  
    * @Title: fileMaxvolume  
    * @author jzhao
    * @Description: 視頻/音頻的信息（主要是提取最大音量）
    * @param @param inputPath
    * @param @throws Exception
    * @return void
    * @throws  
    */  
    public static Double fileMaxVolume(String inputPath)
            throws Exception {
    	//ffmpeg -i audo.mp3 -af "volumedetect" -f null /dev/null
        List<String> command = new ArrayList<String>();
        command.add(ffmpegEXE);
        command.add("-i");
        command.add(inputPath);
        command.add("-af");
        command.add("\"volumedetect\"");
        command.add("-f");
        command.add("null");
        command.add("/dev/null");
        
        ProcessBuilder builder = new ProcessBuilder(command);
        Process process = null;
        try {
            process = builder.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 使用这种方式会在瞬间大量消耗CPU和内存等系统资源，所以这里我们需要对流进行处理
        InputStream errorStream = process.getErrorStream();
        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
        BufferedReader br = new BufferedReader(inputStreamReader);
        
        Double maxVolume = null;
        
        String last = null;
        String line = "";
        while ((line = br.readLine()) != null) {
        	//System.out.println(line);
        	last = line;
        	if(line.indexOf("max_volume") != -1) {
        		last = line;
        		line =  line.substring(line.indexOf(":")+1).replace("dB", "");
        		line = StringUtils.trimToEmpty(line);
        		
        		try {
					maxVolume = Double.parseDouble(line);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
        	}
        }
        if (br != null) {
            br.close();
        }
        if (inputStreamReader != null) {
            inputStreamReader.close();
        }
        if (errorStream != null) {
            errorStream.close();
        }
        if(maxVolume == null)
        	log.error("提取{}最大音量失败：{}",inputPath,last);
        
        log.info("提取{}最大音量:{}",inputPath,maxVolume);
        return maxVolume;
    }

    /**
     * @param time_coverimg   视频的第几秒作为封面图
     * @param videoInputPath  视频的路径
     * @param frame           帧数
     * @param coverOutputPath 视频的封面图的路径
     * @throws Exception
     */
    // ffmpeg.exe -ss 00:00:01 -y -i 视频.mp4 -vframes 1 new.jpg   
    public static void convetor(String time_coverimg, String videoInputPath, int frame, String coverOutputPath)
            throws Exception {

        List<String> command = new ArrayList<String>();
        command.add(ffmpegEXE);
        command.add("-ss");
        command.add(time_coverimg);
        command.add("-y");
        command.add("-i");
        command.add(videoInputPath);
        command.add("-vframes");
        command.add(String.valueOf(frame));
        command.add(coverOutputPath);
        ProcessBuilder builder = new ProcessBuilder(command);
        Process process = null;
        try {
            process = builder.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 使用这种方式会在瞬间大量消耗CPU和内存等系统资源，所以这里我们需要对流进行处理
        InputStream errorStream = process.getErrorStream();
        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
        BufferedReader br = new BufferedReader(inputStreamReader);

        String line = "";
        while ((line = br.readLine()) != null) {
        }
        if (br != null) {
            br.close();
        }
        if (inputStreamReader != null) {
            inputStreamReader.close();
        }
        if (errorStream != null) {
            errorStream.close();
        }

    }
    
    
    
    
   
    
    public static long getFileSize(String filePath) {
    	File file = new File(filePath);
    	return getFileSize(file);
    }
    
    /**
     * 获取文件长度
     * @param file
     */
    public static long getFileSize(File file) {
        if (file.exists() && file.isFile()) {
//            String fileName = file.getName();
//            System.out.println("文件"+fileName+"的大小是："+file.length());
            return file.length();
        }else
        	return -1;
    }

 public static void main(String[] args) {
    String videoInputPath = "G:/videos-resources/180525DFH9X09GR4/video/2018052920010792217.mp4";
    String coverOutputPath = "G:/videos-resources/180525DFH9X09GR4/video/2018052920014289695.jpg";
    try {
      // convetor("00:00:01", videoInputPath, 1, coverOutputPath);
       
        videoInputPath = "C:\\Users\\123456\\Desktop\\setup\\音量\\2222\\bb_di_2.mp4";
       String audioInputPath = "C:\\Users\\123456\\Desktop\\setup\\音量\\2222\\333_2.mp4";
       String videoOutPath = "C:\\Users\\123456\\Desktop\\setup\\音量\\2222\\xxxx.mp4";
       
       
      // convetor(videoInputPath, audioInputPath,  videoOutPath,20);
       
       videoInputPath = "C:\\Users\\123456\\Desktop\\setup\\视频\\222.mp4";
      Double maxVolume = fileMaxVolume(videoInputPath);
      System.out.println(maxVolume);
      
      
      String videoOutputPath = "C:\\Users\\123456\\Desktop\\setup\\音量\\2222\\222+.mp4";
      volumeAdd(videoInputPath,videoOutputPath,7);
     
      maxVolume = fileMaxVolume(videoOutputPath);
      System.out.println(maxVolume);
      
      videoOutputPath = "C:\\Users\\123456\\Desktop\\setup\\音量\\2222\\222-.mp4";
      volumeAdd(videoInputPath,videoOutputPath,-13);
     
      maxVolume = fileMaxVolume(videoOutputPath);
      System.out.println(maxVolume);
      
      
      
    } catch (Exception e) {
       e.printStackTrace();
    }
 }

}
